package main

import (
	"context"
	"log"
	"os"
	"time"

	"gitee.com/general252/pdh"
	"gitee.com/general252/pdh/net"
	"gitee.com/general252/pdh/wmi"
	"github.com/google/gopacket"
	"github.com/google/gopacket/pcap"
)

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
}

func main() {

	pcapDemo()
	//pcapReadFile()

	//monitorDemo()
	//wbemTest()

	//netConnectionsDemo()
}

// 监听进程启动退出事件
func monitorDemo() {

	monitor := wmi.NewProcessMonitor(func(info *wmi.ProcessStartInfo) {
		log.Printf("启动: name: %20v pid: %8v ppid: %8v", info.ProcessName, info.ProcessID, info.ParentProcessID)
	}, func(info *wmi.ProcessStopInfo) {
		log.Printf("退出: name: %20v pid: %8v ppid: %8v exit code: %v", info.ProcessName, info.ProcessID, info.ParentProcessID, info.ExitStatus)
	})

	_ = monitor.Open()
	defer monitor.Close()

	select {}
}

// wmi测试
func wbemTest() {
	wbem := wmi.NewWbemTest()

	// 进程
	if values, err := wbem.GetProcess(); err != nil {
		log.Println(err)
	} else {
		_ = values
		// log.Println(values)
	}

	// 物理内存
	if values, err := wbem.GetPhysicalMemory(); err != nil {
		log.Println(err)
	} else {
		_ = values

		var totalMemory int
		for _, value := range values {
			totalMemory += value.Capacity
		}

		log.Printf("totalMemory: %v", pdh.DataSize(totalMemory))
	}

	// 磁盘驱动
	if values, err := wbem.GetDiskDrive(); err != nil {
		log.Println(err)
	} else {
		_ = values

		for _, value := range values {
			log.Printf("[%v] %v", value.Caption, pdh.DataSize(value.Size))
		}
	}

	// 关联
	if values, err := wbem.GetLogicalDiskWithDiskDrive(); err != nil {
		log.Println(err)
	} else {
		_ = values
		for _, value := range values {
			log.Println(value.Name)
			if value.DiskDrive != nil {
				log.Println(value.DiskDrive.Model)
			}
		}
	}

	// 系统信息
	if value, err := wbem.GetOperatingSystem(); err != nil {
		log.Println(err)
	} else {
		log.Println(value)
	}

}

// 枚举网络连接测试
func netConnectionsDemo() {
	now := time.Now()
	connections, err := net.ConnectionsPid(16460)
	if err != nil {
		log.Println(err)
		return
	}
	log.Println(time.Since(now))

	for _, conn := range connections {
		log.Printf("type: %v, Status: %v  pid: %-10v %v:%v--%v:%v",
			conn.Type,
			conn.Status,
			conn.Pid,
			conn.Laddr.IP, conn.Laddr.Port,
			conn.Raddr.IP, conn.Raddr.Port,
		)
	}
}

// gopacket 抓包过滤器 https://www.cnblogs.com/papering/p/15493262.html
func pcapDemo() {

	h := net.NewPcapHelp()
	log.Println(h.Version())

	var deviceName string
	if values, err := h.EnumDevices(); err != nil {
		log.Println(err)
		return
	} else {
		for _, value := range values {
			if value.Description == "Realtek PCIe GbE Family Controller" {
				deviceName = value.Name
				break
			}

		}
	}

	ctx, ctxFunc := context.WithTimeout(context.TODO(), time.Second*10)
	defer ctxFunc()
	err := h.Capture(ctx, deviceName, func(packet gopacket.Packet) {
		log.Printf("%v %v", packet.Metadata().CaptureInfo.Length, packet.Metadata().CaptureInfo.CaptureLength)
	}, nil, "")
	if err != nil {
		log.Println(err)
	}

	log.Println("end")
	pdh.WaitForAppQuitSignal(true, func(sign os.Signal) {
		log.Println(sign)
	})
}

func pcapReadFile() {
	handle, err := pcap.OpenOffline("test.pcap")
	if err != nil {
		return
	}

	defer handle.Close()

	handle.ReadPacketData()

	packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
	var i = 1
	for packet := range packetSource.Packets() {
		m := packet.Metadata()
		log.Printf("%v %v %v %v", i, m.Timestamp, m.Length, m.CaptureLength)
		i++
	}
}
